﻿namespace Cos.Core.Attributes
{
    using System;

    using Microsoft.Practices.Unity.InterceptionExtension;

    internal class InterceptorDefaultCallHandler : ICallHandler
    {
        public event EventHandler<InterceptorExecutingContextEventArg> Executing;
        public event EventHandler<InterceptorExecutedContextEventArg> Executed;
        public event EventHandler<InterceptorErrorContextEventArg> Error;

        public InterceptorDefaultCallHandler(int order)
        {
            this.Order = order;
        }

        public int Order { get; set; }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn output = null;

            var e = new InterceptorExecutingContextEventArg(input);
            try
            {
                if (this.Executing != null)
                {
                    this.Executing(this, e);

                    if (e.Cancel)
                    {
                        return null;
                    }
                }

                output = getNext()(input, getNext);

                if (output.Exception != null && this.Error != null)
                {
                    this.Error(this, new InterceptorErrorContextEventArg(input, output.Exception));
                }

                return output;
            }
            finally
            {
                if (!e.Cancel && this.Executed != null)
                {
                    this.Executed(this, new InterceptorExecutedContextEventArg(input, output));
                }
            }
        }
    }
}
